package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.ariticle.IArticleClient;
import com.heima.apis.use.IUseClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.ApCommentRepayLike;
import com.heima.comment.vo.CommentRepayListVo;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleCommentDto;
import com.heima.model.article.dtos.DelCommentDto;
import com.heima.model.comment.dtos.CommentConfigDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentManageDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.service.CommentManageService;
import com.heima.wemedia.service.WmUserService;
import com.heima.wemedia.util.ThreadLocalUtil;
import com.mongodb.client.result.DeleteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentManageServiceImpl implements CommentManageService {
    @Autowired
    private IArticleClient iArticleClient;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private WmUserService wmUserService;


    @Autowired
    private CacheService cacheService;
    @Autowired
    private IUseClient iUseClient;


    @Override
    public PageResponseResult list(CommentManageDto dto) {
        //进行分页查询
        Query apCommentsQuery = Query.query(Criteria.where("articleId").is(dto.getArticleId()))
                .with(Sort.by(Sort.Direction.DESC,"updatedTime"))
                .skip((dto.getPage()-1)*dto.getSize())
                .limit(dto.getSize());
        List<ApComment> apComments = mongoTemplate.find(apCommentsQuery, ApComment.class);

        List<CommentRepayListVo> collect = apComments.stream().map(apComment -> {
            CommentRepayListVo commentRepayListVo = new CommentRepayListVo();
            commentRepayListVo.setApComments(apComment);
            Query commentId = Query.query(Criteria.where("commentId").is(apComment.getId())).with(Sort.by(Sort.Direction.DESC, "updatedTime"));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(commentId, ApCommentRepay.class);
            commentRepayListVo.setApCommentRepays(apCommentRepays);


            return commentRepayListVo;
        }).collect(Collectors.toList());
        Query countsQuery = Query.query(Criteria.where("articleId").is(dto.getArticleId()))
                .with(Sort.by(Sort.Direction.DESC,"updatedTime"));


        //查询总数
        long count = mongoTemplate.count(countsQuery, ApComment.class);


        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), count);
        pageResponseResult.setData(collect);
        return pageResponseResult;
    }

    @Override
    public PageResponseResult findNewsComments(ArticleCommentDto dto) {
        //将dto补全
        dto.setWmUserId(ThreadLocalUtil.get());
        //调用接口将对应的Article查出
        PageResponseResult byPage = iArticleClient.findByPage(dto);

        return byPage;
    }

    @Override
    public ResponseResult delComment(String commentId) {

        Query commentQ = Query.query(Criteria.where("_id").is(commentId));
        ApComment coment = mongoTemplate.findOne(commentQ, ApComment.class);
        Long articleId = coment.getArticleId();

        //得去更改文章的点赞
        Integer delLikes = 0;
        //去删除文章的评论
        Integer delComments = 1;
        //去查询评论的评论
        Query commentIdQuery = Query.query(Criteria.where("commentId").is(commentId));
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(commentIdQuery, ApCommentRepay.class);
        delComments = delComments+apCommentRepays.size();

        for (ApCommentRepay apCommentRepay : apCommentRepays) {
            //去删除评论的评论的喜欢操作
            String id = apCommentRepay.getId();
            Query commentRepayIdQuery = Query.query(Criteria.where("commentRepayId").is(id));
            DeleteResult removeCommentRepayLikeResult = mongoTemplate.remove(commentRepayIdQuery, ApCommentRepayLike.class);
            delLikes =delLikes+Integer.valueOf(String.valueOf(removeCommentRepayLikeResult.getDeletedCount()));
        }
        mongoTemplate.remove(commentIdQuery,ApCommentRepay.class);
        DeleteResult removeApCommentLikeResult = mongoTemplate.remove(commentIdQuery, ApCommentLike.class);

        delLikes =delLikes+Integer.valueOf(String.valueOf(removeApCommentLikeResult.getDeletedCount()));
        //将删除数量同步到app端
        DelCommentDto delCommentDto = new DelCommentDto();
        delCommentDto.setArticleId(articleId);
        delCommentDto.setDelLikes(delLikes);
        delCommentDto.setDelComments(delComments);
        iArticleClient.delComment(delCommentDto);
        return ResponseResult.okResult("删除成功");
    }

    @Override
    public ResponseResult delCommentRepay(String commentRepayId) {
        Query commentRepayIdQuery = Query.query(Criteria.where("_id").is(commentRepayId));

        ApCommentRepay apCommentRepay = mongoTemplate.findOne(commentRepayIdQuery, ApCommentRepay.class);
        String commentId = apCommentRepay.getCommentId();

        Query commentQ = Query.query(Criteria.where("_id").is(commentId));
        ApComment coment = mongoTemplate.findOne(commentQ, ApComment.class);
        Long articleId = coment.getArticleId();

        //得去更改文章的点赞
        Integer delLikes = 0;
        //去删除文章的评论
        Integer delComments = 1;

        //去查询评论的评论
        Query commentRepayIdQuery1 = Query.query(Criteria.where("commentRepayId").is(commentRepayId));
        DeleteResult apCommentRepayLikeResult = mongoTemplate.remove(commentRepayIdQuery, ApCommentRepayLike.class);
        mongoTemplate.remove(commentRepayIdQuery,ApCommentRepay.class);

        coment.setReply(coment.getReply()-1);
        Integer delRepllikes = Integer.valueOf(String.valueOf(apCommentRepayLikeResult.getDeletedCount()));
        delLikes= delLikes+delRepllikes;

        coment.setLikes(coment.getLikes()-delRepllikes);
        //更新Comment
        mongoTemplate.save(coment);

        //去更新app端文章的数据
        DelCommentDto delCommentDto = new DelCommentDto();
        delCommentDto.setArticleId(articleId);
        delCommentDto.setDelLikes(delLikes);
        delCommentDto.setDelComments(delComments);
        iArticleClient.delComment(delCommentDto);
        return ResponseResult.okResult("操作成功");
    }

    @Override
    public ResponseResult updateCommentStatus(CommentConfigDto dto) {

        ResponseResult responseResult =iArticleClient.changeArticleStatus(dto);
        if (responseResult == null || responseResult.getCode() != 200) {
            return ResponseResult.errorResult(500,"操作失败");
        }
        if (dto.getOperation() == 2) {
            //删除manggoDB的东西
            Query articleId = Query.query(Criteria.where("articleId").is(dto.getArticleId()));
            List<ApComment> apComments = mongoTemplate.find(articleId, ApComment.class);

            for (ApComment apComment : apComments) {
                String id = apComment.getId();
                Query commentId = Query.query(Criteria.where("commentId").is(id));
                List<ApCommentRepay> apCommentRepays = mongoTemplate.find(commentId, ApCommentRepay.class);
                for (ApCommentRepay apCommentRepay : apCommentRepays) {
                    String id1 = apCommentRepay.getId();
                    Query commentRepayId = Query.query(Criteria.where("commentRepayId").is(id1));
                    mongoTemplate.remove(commentRepayId,ApCommentRepayLike.class);
                }
                mongoTemplate.remove(commentId,ApCommentRepay.class);
                mongoTemplate.remove(commentId,ApCommentLike.class);
            }
            mongoTemplate.remove(articleId,ApComment.class);

        }

        return ResponseResult.okResult("操作成功");
    }

    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        if (!auditText(dto.getContent())) {
            //审核未通过
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        Integer userId = ThreadLocalUtil.get();

        WmUser byId = wmUserService.getById(userId);

        Integer apUserId = byId.getApUserId();


        ResponseResult userResponseResult = iUseClient.findById(apUserId);
        if (userResponseResult.getCode()!=200 || userResponseResult.getData()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        }

        Object userJsonObject = userResponseResult.getData();
        String userJson = JSON.toJSONString(userJsonObject);
        ApUser user= JSON.parseObject(userJson,ApUser.class);


        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(apUserId);
        apCommentRepay.setAuthorName(user.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());

        mongoTemplate.save(apCommentRepay);

        Query id = Query.query(Criteria.where("_id").is(dto.getCommentId()));

        ApComment apCommentINDb = mongoTemplate.findOne(id, ApComment.class);
        apCommentINDb.setReply(apCommentINDb.getReply()+1);
        apCommentINDb.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentINDb);

        return ResponseResult.okResult("评论成功");

    }

    private boolean auditText(String text){

        Set<String> wmSensitiveset = cacheService.setMembers(WemediaConstants.CATCH_KEY_SENSITIVE);
        SensitiveWordUtil.initMap(wmSensitiveset);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (!stringIntegerMap.isEmpty()){
            return false;
        }

        return true;
    }

    @Override
    public ResponseResult like(CommentLikeDto dto) {
        Query queryApComment = Query.query(Criteria.where("_id").is(dto.getCommentId()));
        ApComment apCommentInDb= mongoTemplate.findOne(queryApComment, ApComment.class);
        if (dto.getOperation()==0){
            apCommentInDb.setLikes(apCommentInDb.getLikes()-1);
        } else if (dto.getOperation() == 1) {
            apCommentInDb.setLikes(apCommentInDb.getLikes()+1);
        }
        //更新更新时间
        apCommentInDb.setUpdatedTime(new Date());

        Query queryApCommentLike = Query.query(Criteria.where("authorId")
                .is(com.heima.comment.util.ThreadLocalUtil.get())
                .and("commentId")
                .is(dto.getCommentId()));

        ApCommentLike apCommentLikeInDb= mongoTemplate.findOne(queryApCommentLike, ApCommentLike.class);


        Integer userId = ThreadLocalUtil.get();

        WmUser byId = wmUserService.getById(userId);

        Integer apUserId = byId.getApUserId();
        if(apCommentLikeInDb==null){
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(dto.getCommentId());
            apCommentLike.setAuthorId(apUserId);
            apCommentLike.setOperation(Integer.valueOf(dto.getOperation()));
        }else {
            apCommentLikeInDb.setOperation(Integer.valueOf(dto.getOperation()));
        }
        HashMap hashMap = new HashMap();
        hashMap.put("likes",apCommentInDb.getLikes());


        return ResponseResult.okResult(hashMap);
    }
}
